#include <iostream>
#include "anydemo.pb.h"

#include <google/protobuf/any.h>
#include <google/protobuf/any.pb.h>
using namespace std;
typedef google::protobuf::Message GPMessage;
typedef google::protobuf::Any Any;

#include "pbmsg.hpp"
#include "utils.h"

void checkAny(const Test& test) {


    if (!test.has_dynamicanydata()) {


        cout << "not has_data" << endl;
        return;
    }

    Apply_data data1;
    Apply_list list1;
    //判断是否是和发的proto any
    //if (!test.mutable_data()->UnpackTo(&data1)) {


    if (test.dynamicanydata().Is<Apply_data>()) {
        //解析
        if (test.dynamicanydata().UnpackTo(&data1)) {


            cout << data1.apply_data_id() << endl;
            cout << "unpackTo data success" << endl;
        }
        else {


            cout << "unpackTo data error" << endl;
        }
    }
    else {


        cout << "is not apply_data" << endl;
    }

    if (test.dynamicanydata().Is<Apply_list>()) {



        //解析
        if (test.dynamicanydata().UnpackTo(&list1)) {


            cout << list1.apply_list_id() << endl;
            cout << "unpackTo list success" << endl;
        }
        else {


            cout << "unpackTo list error" << endl;;
        }
    }
    else {


        cout << "is not apply_list" << endl;
    }
}
#include "google/protobuf/arena.h"
int main() {


    Test test;
    Apply_data data;
    data.set_apply_data_id(3000);
    data.set_apply_time(20230701);


    //Apply_list list;
    //list.set_apply_list_id(222);
    test.set_id(123);
    test.mutable_dynamicanydata()->PackFrom(data);
    auto dy = test.dynamicanydata();

    auto x = test.dynamicanydata().type_url();


    auto n = test.GetDescriptor()->FindFieldByName("dynamicAnyData")->message_type()->full_name();
    cout << n << endl;
        std::string output;
    test.SerializeToString(&output);


    printf("-----------------\n  result length = %zu\n", output.length());
    auto s = dump_mem_to_str(output.data(), output.length(), 20, 7);
    printf("%s", s.c_str());
    printf("-----------------\n");



    //找到any数据 解析
    checkAny(test);
    //----------------------


#if 0

    //设置any数据

    cout << "set apply_list data:" << endl;
    test.mutable_dynamicanydata()->PackFrom(list);
    //找到any数据 解析
    checkAny(test);

    auto yy = test.GetMetadata();

    auto d = yy.descriptor->FindFieldByName("dynamicAnyData");

    auto xx = test.mutable_dynamicanydata();

    //----------------------
    //清空
    cout << "clear data:" << endl;
    test.clear_dynamicanydata();
    checkAny(test);
#endif
    std::string err;
    std::shared_ptr<pbmsg_t>  apply_data = pbmsg_t::create("../../example/protos/anydemo.proto", "Apply_data", &err);
    apply_data->set_attr("apply_data_id", uint32_t(3000));
    apply_data->set_attr("apply_time", uint64_t(20230701));


    std::shared_ptr<pbmsg_t>  test_data = pbmsg_t::create("../../example/protos/anydemo.proto", "Test");

    test_data->set_attr("id", 123);

    google::protobuf::Arena arena;
    Message* msg = nullptr;
    
    test_data->get_attr("dynamicAnyData", msg);
    auto any = static_cast<Any*>(msg)->New(&arena);
    auto ab = apply_data->get_msg(false);
    any->PackFrom(*ab);    

    test_data->set_attr("dynamicAnyData", static_cast<Message*>(any));

    output = test_data->get_bin();
    printf("-----------------\n  result length = %zu\n", output.length());
    s = dump_mem_to_str(output.data(), output.length(), 20, 7);
    printf("%s", s.c_str());
    printf("-----------------\n");


    return  0;
}